﻿using System.Text;
using DaphneProfiBase;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using GameEngine;
using EngineAdmin;
using ComputerEngine;
using RTF;
using System.Drawing;

namespace DaphneControls.ViewModel
{
    /// <summary>
    /// ViewModel for Engine Match Output Window Pane
    /// </summary>
    public class EngineMatchOutputVM : ViewModelBase
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public EngineMatchOutputVM()
        {
            // message for empty output
            Messenger.Default.Register<NotificationMessage>(this, (nm) =>
                {
                    if (nm.Notification == Notify.NoEngineMatchInfo)
                    {
                        // TO-DO Move to resources
                        EngineOutput = "Current checkers board is not running an engine match.";
                        RaisePropertyChanged("EngineOutput");
                    }
                });

            // message for the output
            Messenger.Default.Register<NotificationMessage<InfoEngineMatch>>(this, (nm) =>
                {
                    if (nm.Notification == Notify.EngineMatchInfo)
                    {
                        DisplayInfoOutput(nm.Content);
                    }                   
                });
        }

        /// <summary>
        /// Engine Output Binding Property
        /// </summary>
        public string EngineOutput
        { get; set; }

        private void DisplayInfoOutput(InfoEngineMatch info)
        {
            EngineOutput = BuildOutput(info);
            RaisePropertyChanged("EngineOutput");
        }

        /// <summary>
        /// TO-DO: Refactor to the resources
        /// </summary>
        private string BuildOutput(InfoEngineMatch info)
        {
            RTFBuilderbase sb = new RTFBuilder();

            // checkers type
            sb.FontStyle(FontStyle.Bold | FontStyle.Underline)
                .FontSize(25).AppendLine("Engine Match Information");
            sb.FontStyle(System.Drawing.FontStyle.Bold).Append("Checkers Type: ");
            switch (info.CheckersType)
            {
                case enumGameType.Czech:
                    sb.Append("Czech Draughts");
                    break;
                case enumGameType.English:
                    sb.Append("English Checkers");
                    break;
                case enumGameType.International:
                    sb.Append("Internatinal Draughts");
                    break;
                case enumGameType.Italian:
                    sb.Append("Italian Draughts");
                    break;
                case enumGameType.Russian:
                    sb.Append("Russian Draughts");
                    break;
                default:
                    sb.Append("Unknown");
                    break;
            }
            sb.AppendLine();

            sb.FontStyle(FontStyle.Bold).Append("Rounds: ").AppendLine(string.Format("{0}/{1}", info.RoundsPassed, info.RoundsTotal));
            sb.FontStyle(FontStyle.Bold).Append("White Wins: ").AppendLine(string.Format("{0}", info.WhiteWins));
            sb.FontStyle(FontStyle.Bold).Append("Black Wins: ").AppendLine(string.Format("{0}", info.BlackWins));
            sb.FontStyle(FontStyle.Bold).Append("Draws: ").AppendLine(string.Format("{0}", info.Draws));
            sb.AppendLine();
            
            sb.FontStyle(FontStyle.Bold | FontStyle.Underline)
                .FontSize(25).AppendLine("White Engine Output:");
            AppendMoveOutput(sb, info.WhiteEngineOutput);
            sb.AppendLine();
            sb.FontStyle(FontStyle.Bold | FontStyle.Underline)
                .FontSize(25).AppendLine("Black Engine Output:");
            AppendMoveOutput(sb, info.BlackEngineOutput);
            sb.AppendLine();

            sb.FontStyle(FontStyle.Bold | FontStyle.Underline)
                .FontSize(25).AppendLine("White Engine Config:");
            AppendInternalEngineOutput(sb, info.WhiteEngineConfig.InternalEngineSettings);
            sb.AppendLine();
            sb.FontStyle(FontStyle.Bold | FontStyle.Underline)
                .FontSize(25).AppendLine("Black Engine Config:");
            AppendInternalEngineOutput(sb, info.BlackEngineConfig.InternalEngineSettings);

            return sb.ToString();
        }

        private void AppendMoveOutput(RTFBuilderbase sb, EngineMoveOutput output)
        {
            sb.FontStyle(FontStyle.Bold).Append("Depth: ").AppendLine(string.Format("{0}/{1}", output.MaxDepth, output.MaxCalmPositionDepth));
            sb.FontStyle(FontStyle.Bold).Append("Cache Hit: ").AppendLine(string.Format("{0}%", output.CacheHit));
            sb.FontStyle(FontStyle.Bold).Append("Nodes: ").AppendLine(string.Format("{0}", output.NumberOfNodes));
            sb.FontStyle(FontStyle.Bold).Append("Nodes per sec: ").AppendLine(string.Format("{0}", output.NodesPerSecond));         
        }

        private void AppendInternalEngineOutput(RTFBuilderbase sb, EngineSettings s)
        {
            string sSearchType = string.Empty;
            switch (s.SearchType)
            {
                case eSearchType.NegaMax:
                    sSearchType = "NegaMax";
                    break;
                case eSearchType.AlphaBeta:
                    sSearchType = "Alpha-Beta";
                    break;
                case eSearchType.MTDf:
                    sSearchType = "MTDf";
                    break;
                case eSearchType.PVS:
                    sSearchType = "PVS";
                    break;
            }

            sb.FontStyle(FontStyle.Bold).Append("Search Type: ").AppendLine(string.Format("{0}", sSearchType));
            sb.FontStyle(FontStyle.Bold).Append("Max depth: ").AppendLine(string.Format("{0}", s.MaxDepth));
            sb.FontStyle(FontStyle.Bold).Append("Search time: ").AppendLine(string.Format("{0}ms", s.MaxSeconds * 1000));
            sb.FontStyle(FontStyle.Bold).Append("Cache: ").AppendLine(string.Format("{0}", s.UseCache ? "On" : "Off"));
            sb.FontStyle(FontStyle.Bold).Append("Tablebases: ").AppendLine(string.Format("{0}", s.UseEndGameDB ? "On" : "Off"));
            sb.FontStyle(FontStyle.Bold).Append("Killer: ").AppendLine(string.Format("{0}", s.UseKillerMoves ? "On" : "Off"));
            sb.FontStyle(FontStyle.Bold).Append("History heur.: ").AppendLine(string.Format("{0}", s.UseHistoryHeuristics ? "On" : "Off"));
            sb.FontStyle(FontStyle.Bold).Append("Position Strategy: ").AppendLine(string.Format("{0}", s.UsePositionStrategy ? "On" : "Off"));
            sb.FontStyle(FontStyle.Bold).Append("Cache size: ").AppendLine(string.Format("{0} MB", s.CacheSizeMB));
        }
    }
}